import java
import prefuse
import edu
import javax
import prefuse.Display as Display;
import prefuse.Visualization as Visualization;
import prefuse.action.ActionList as ActionList;
import prefuse.action.RepaintAction as RepaintAction;
import prefuse.action.assignment.ColorAction as ColorAction;
import prefuse.action.layout.graph.ForceDirectedLayout as ForceDirectedLayout;
import prefuse.activity.Activity as Activity;
import prefuse.render.DefaultRendererFactory as DefaultRendererFactory;
import prefuse.render.LabelRenderer as LabelRenderer;
import prefuse.util.force.ForceSimulator;
import prefuse.util.ui.JForcePanel;
import prefuse.visual.VisualItem as VisualItem
import prefuse.util.ColorLib as ColorLib
import xml,org
from java.io import *
from prefuse.controls import *

from mfuncs import size,nonzeros

## very primitive code to read GML files
def readGML(filename):
	tokens = StreamTokenizer(java.io.FileInputStream(filename));
	capture=False
	tokens.quoteChar(34)
	sourcet=-1
	dest = -1
	idx = -1
	hmap={}
	edgeList=[]
	nodeList=[]
	preG = prefuse.data.Graph()
	preG.addColumn("label",java.lang.String,"p")
	while  -1 != tokens.nextToken():
		if tokens.sval =="id":
			tokens.nextToken()
			idx = int(tokens.nval)
		if tokens.sval == "label":
			tokens.nextToken()
			if tokens.ttype == 34:
				nodeList += [(idx,tokens.sval)]
			else:
				tokens.pushBack()
		elif tokens.sval == "edge":
			tokens.nextToken()
			tokens.nextToken()
			tokens.nextToken()
			sourcet = int(tokens.nval)
			tokens.nextToken()
			tokens.nextToken()
			dest = int(tokens.nval)
			tokens.nextToken()
			tokens.nextToken()
			if tokens.ttype == 34:
				edgeList += [(sourcet,dest,tokens.sval)]
			else:
				tokens.pushBack()
	
	for v in nodeList:
		n = preG.addNode()
		n.setString("label",v[1])
		
	#E = preG.getEdgeTable() 
	#E.addColumn("ename", java.lang.String,"d")
	#preG.setEdgeTable(E)
	for e in edgeList:
		preG.addEdge(e[0],e[1])
	return preG



class PyFactory(prefuse.render.DefaultRendererFactory):
	tr = LabelRenderer();
	edger = prefuse.render.EdgeRenderer(prefuse.Constants.EDGE_ARROW_NONE)
	def __init__(self):
		self.tr.setRoundedCorner(8, 8);
		self.tr.setTextField("label")
		self.edger.setDefaultLineWidth(2.0)
	def getRenderer(self,v):
		#print v
		if v.isInGroup("graph.edges"):
			return self.edger
		else:
			return self.tr

## ok.. need to conver graphML id tags set by YFiles to the type readable by jung
## or I can read it myself..
## this function converts a JUNG GraphML object into a Prefuse graph

def loadAsPrefuse(filename):
	r = edu.uci.ics.jung.io.GraphMLFile()
	G = r.load(filename)
	preG = prefuse.data.Graph()
	preG.addColumn("label",java.lang.String,"protein")
	V = G.getVertices()
	NodeMap = {}
	c=0
	for v in V:
		m = v.getUserDatumKeyIterator()
		#print dir(v)
		#print v.getUserDatum(m)
		
		n = None
		n = preG.addNode()
		n.setString("label",c.__str__())
		NodeMap[v] = n
		c=c+1
	E = G.getEdges()
	for e in E:
		n1 = e.getSource()
		n2 = e.getDest()
		x = NodeMap[n1]  
		y = NodeMap[n2]
		preG.addEdge(x,y)
	return preG



def ExpressionCorrelationNetwork(E):
	pass



class BipartiteLayout(prefuse.action.layout.Layout):

	# sort in terms of number of genes regulated
	# find overlap
	tf_x={}
	
	def __init__(self,group):
		super(group)
		
		# find each gene regulated by more than 1 TF
		# rank genes by their regulator count  O(n)
		# layout these regulators and genes
		# add remaining regulators and genes
	
	def run(self,frac):
		viz = self.m_vis
		ts = viz.getGroup(self.group); 
		nn = ts.getTupleCount();
		r = getLayoutBounds();  
		height = r.getHeight();
		width = r.getWidth();
		cx = r.getCenterX();
		cy = r.getCenterY();

def prefuseNetworkViz(G,layout=None):
	graph = "graph"
	edges = "graph.edges"
	nodes = "graph.nodes"
	viz = prefuse.Visualization()
	tr = PyFactory()
	viz.setRendererFactory(tr);
	viz.addGraph(graph, G)
	fill = ColorAction(nodes,VisualItem.FILLCOLOR, ColorLib.rgb(200,200,255));
	draw = ActionList();
	draw.add(fill);
	draw.add(ColorAction(nodes, VisualItem.STROKECOLOR, 0));
	draw.add(ColorAction(nodes, VisualItem.TEXTCOLOR, ColorLib.rgb(0,0,0)));
	draw.add(ColorAction(edges, VisualItem.FILLCOLOR, ColorLib.rgb(100,100,75)));
	draw.add(ColorAction(edges, VisualItem.STROKECOLOR, ColorLib.rgb(100,100,75)));
	viz.putAction("draw",draw)

	if layout == "tree":
		animate = ActionList();
		#lg = prefuse.action.layout.graph.NodeLinkTreeLayout(graph,prefuse.Constants.ORIENT_TOP_BOTTOM,2,10,20)
		#lg = prefuse.action.layout.GridLayout(graph)
		lg = prefuse.action.layout.graph.BalloonTreeLayout(graph)
		animate.add(lg)
#		lg.setMaxIterations() 
	else:
		animate = ActionList(Activity.INFINITY);
		animate.add(ForceDirectedLayout(graph,False));
		
	animate.add(draw)
	animate.add(fill)
	animate.add(RepaintAction());
	display = prefuse.Display(viz)
	# add controls
	display.addControlListener(FocusControl(1));
        display.addControlListener(DragControl());
        display.addControlListener(PanControl());
        display.addControlListener(ZoomControl());
        display.addControlListener(WheelZoomControl());
        display.addControlListener(ZoomToFitControl());
        display.addControlListener(NeighborHighlightControl());
	viz.putAction("init",animate)
	viz.runAfter("init","draw");
	display.setVisible(True)
	display.setHighQuality(True)
	viz.run("init")
	viz.run("draw")
	display.setSize(220,340)
	display.show() 	
	return display

def TFNetworkViz(X):
	G = prefuse.data.Graph(True)  # creates directed network
	#need to set the schema
	G.addColumn("label",java.lang.String,"TF")
	[r,c]=size(X)
	nodeMap = {}
	Nodes = X.columnNames[1:len(X.columnNames)] + X.rowNames[1:len(X.rowNames)]
	for j in Nodes:
		n = G.addNode()
		n.setString("label",j.__str__())
		nodeMap[j] = n

	for x in X.columnNames[1:len(X.columnNames)]:
			tf = X.columnNames.index(x)
			ny = nodeMap[x]
			genes = nonzeros(X[:,tf])
			for g in genes:
			#print g
				try:
					nx = nodeMap[X.rowNames[g[0]]]
					G.addEdge(ny,nx)
				except:
					pass

	return prefuseNetworkViz(G,'tree')


def registerWithSearchEng(V):
	# find indexable tupules to register with lucene

	if False == desktop.SearchEnabled:
		return False
	return True